{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "db4ccfed-4c26-447e-9ca1-d1af06432cfc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 忽略警告提示\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    " \n",
    "#导入处理数据包\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import time\n",
    "import psutil"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "eec6de5b-c685-4f27-a0ee-424fbf83a914",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练数据集: (891, 12) 测试数据集: (418, 11)\n"
     ]
    }
   ],
   "source": [
    "#导入数据\n",
    "#训练数据集\n",
    "train = pd.read_csv(\"./train.csv\")\n",
    "#测试数据集\n",
    "test  = pd.read_csv(\"./test.csv\")\n",
    "print ('训练数据集:',train.shape,'测试数据集:',test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "028f5231-f1e6-4eea-93d6-edd4c8738c94",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "合并后的数据集: (1309, 12)\n"
     ]
    }
   ],
   "source": [
    "starttime = time.time()\n",
    "#合并数据集，方便同时对两个数据集进行清洗\n",
    "full = train._append( test , ignore_index = True )\n",
    " \n",
    "print ('合并后的数据集:',full.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6fd927de-fd63-433c-ad40-0b5dac95b988",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1309 entries, 0 to 1308\n",
      "Data columns (total 12 columns):\n",
      " #   Column       Non-Null Count  Dtype  \n",
      "---  ------       --------------  -----  \n",
      " 0   PassengerId  1309 non-null   int64  \n",
      " 1   Survived     891 non-null    float64\n",
      " 2   Pclass       1309 non-null   int64  \n",
      " 3   Name         1309 non-null   object \n",
      " 4   Sex          1309 non-null   object \n",
      " 5   Age          1046 non-null   float64\n",
      " 6   SibSp        1309 non-null   int64  \n",
      " 7   Parch        1309 non-null   int64  \n",
      " 8   Ticket       1309 non-null   object \n",
      " 9   Fare         1308 non-null   float64\n",
      " 10  Cabin        295 non-null    object \n",
      " 11  Embarked     1307 non-null   object \n",
      "dtypes: float64(3), int64(4), object(5)\n",
      "memory usage: 122.8+ KB\n"
     ]
    }
   ],
   "source": [
    "# 查看每一列的数据类型，和数据总数\n",
    "full.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "931406a3-6cff-4a10-80b8-15fb229ca0bc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1309 entries, 0 to 1308\n",
      "Data columns (total 12 columns):\n",
      " #   Column       Non-Null Count  Dtype  \n",
      "---  ------       --------------  -----  \n",
      " 0   PassengerId  1309 non-null   int64  \n",
      " 1   Survived     891 non-null    float64\n",
      " 2   Pclass       1309 non-null   int64  \n",
      " 3   Name         1309 non-null   object \n",
      " 4   Sex          1309 non-null   object \n",
      " 5   Age          1309 non-null   float64\n",
      " 6   SibSp        1309 non-null   int64  \n",
      " 7   Parch        1309 non-null   int64  \n",
      " 8   Ticket       1309 non-null   object \n",
      " 9   Fare         1309 non-null   float64\n",
      " 10  Cabin        295 non-null    object \n",
      " 11  Embarked     1307 non-null   object \n",
      "dtypes: float64(3), int64(4), object(5)\n",
      "memory usage: 122.8+ KB\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "我们发现数据总共有1309行。\n",
    "其中数据类型列：年龄（Age）、船舱号（Cabin）里面有缺失数据：\n",
    "1）年龄（Age）里面数据总数是1046条，缺失了1309-1046=263，缺失率263/1309=20%\n",
    "2）船票价格（Fare）里面数据总数是1308条，缺失了1条数据\n",
    "对于数据类型，处理缺失值最简单的方法就是用平均数来填充缺失值\n",
    "'''\n",
    "#年龄(Age)\n",
    "full['Age']=full['Age'].fillna( full['Age'].mean() )\n",
    "#船票价格(Fare)\n",
    "full['Fare'] = full['Fare'].fillna( full['Fare'].mean() )\n",
    "full.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "905c5482-92b4-4e25-a1bd-3e715c1d0d6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "分类变量Embarked，看下最常见的类别，用其填充\n",
    "'''\n",
    "full['Embarked'].value_counts()\n",
    "'''\n",
    "从结果来看，S类别最常见。我们将缺失值填充为最频繁出现的值：\n",
    "S=英国南安普顿Southampton\n",
    "'''\n",
    "full['Embarked'] = full['Embarked'].fillna( 'S' )\n",
    "\n",
    "#船舱号（Cabin）：查看里面数据长啥样\n",
    "full['Cabin'].head()\n",
    " \n",
    "#缺失数据比较多，船舱号（Cabin）缺失值填充为U，表示未知（Uknow） \n",
    "full['Cabin'] = full['Cabin'].fillna( 'U' )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d200c56a-d122-4d81-ac32-2e1071756404",
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "将性别的值映射为数值\n",
    "男（male）对应数值1，女（female）对应数值0\n",
    "'''\n",
    "sex_mapDict={'male':1,\n",
    "            'female':0}\n",
    "#map函数：对Series每个数据应用自定义的函数计算\n",
    "full['Sex']=full['Sex'].map(sex_mapDict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "682adc42-c547-4c55-896f-a9d615f22c83",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Embarked_C</th>\n",
       "      <th>Embarked_Q</th>\n",
       "      <th>Embarked_S</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Embarked_C  Embarked_Q  Embarked_S\n",
       "0           0           0           1\n",
       "1           1           0           0\n",
       "2           0           0           1\n",
       "3           0           0           1\n",
       "4           0           0           1"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#存放提取后的特征\n",
    "embarkedDf = pd.DataFrame()\n",
    " \n",
    "'''\n",
    "使用get_dummies进行one-hot编码，产生虚拟变量（dummy variables），列名前缀是Embarked\n",
    "'''\n",
    "embarkedDf = pd.get_dummies( full['Embarked'] , prefix='Embarked' )\n",
    "embarkedDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f378f40e-10f0-4004-8fdc-e4a7db49c433",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pclass_1</th>\n",
       "      <th>Pclass_2</th>\n",
       "      <th>Pclass_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Pclass_1  Pclass_2  Pclass_3\n",
       "0         0         0         1\n",
       "1         1         0         0\n",
       "2         0         0         1\n",
       "3         1         0         0\n",
       "4         0         0         1"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,embarkedDf],axis=1)\n",
    " \n",
    "'''\n",
    "因为已经使用登船港口(Embarked)进行了one-hot编码产生了它的虚拟变量（dummy variables）\n",
    "所以这里把登船港口(Embarked)删掉\n",
    "'''\n",
    "full.drop('Embarked',axis=1,inplace=True)\n",
    "'''\n",
    "上面drop删除某一列代码解释：\n",
    "因为drop(name,axis=1)里面指定了name是哪一列，比如指定的是A这一列，axis=1表示按行操作。\n",
    "那么结合起来就是把A列里面每一行删除，最终结果是删除了A这一列.\n",
    "简单来说，使用drop删除某几列的方法记住这个语法就可以了：drop([列名1,列名2],axis=1)\n",
    "'''\n",
    "\n",
    "'''\n",
    "客舱等级(Pclass):\n",
    "1=1等舱，2=2等舱，3=3等舱\n",
    "'''\n",
    "#存放提取后的特征\n",
    "pclassDf = pd.DataFrame()\n",
    " \n",
    "#使用get_dummies进行one-hot编码，列名前缀是Pclass\n",
    "pclassDf = pd.get_dummies( full['Pclass'] , prefix='Pclass' )\n",
    "pclassDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "58634c02-8c93-428e-b2cc-ec89e1bca030",
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,pclassDf],axis=1)\n",
    " \n",
    "#删掉客舱等级（Pclass）这一列\n",
    "full.drop('Pclass',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "13cd624a-12a3-464d-aa23-1abb9016b2a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "定义函数：从姓名中获取头衔\n",
    "'''\n",
    "def getTitle(name):\n",
    "    str1=name.split( ',' )[1] #Mr. Owen Harris\n",
    "    str2=str1.split( '.' )[0]#Mr\n",
    "    #strip() 方法用于移除字符串头尾指定的字符（默认为空格）\n",
    "    str3=str2.strip()\n",
    "    return str3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2067a325-47ad-4903-9235-c23d94828028",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Master</th>\n",
       "      <th>Miss</th>\n",
       "      <th>Mr</th>\n",
       "      <th>Mrs</th>\n",
       "      <th>Officer</th>\n",
       "      <th>Royalty</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Master  Miss  Mr  Mrs  Officer  Royalty\n",
       "0       0     0   1    0        0        0\n",
       "1       0     0   0    1        0        0\n",
       "2       0     1   0    0        0        0\n",
       "3       0     0   0    1        0        0\n",
       "4       0     0   1    0        0        0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#存放提取后的特征\n",
    "titleDf = pd.DataFrame()\n",
    "#map函数：对Series每个数据应用自定义的函数计算\n",
    "titleDf['Title'] = full['Name'].map(getTitle)\n",
    " \n",
    "'''\n",
    "定义以下几种头衔类别：\n",
    "Officer政府官员\n",
    "Royalty王室（皇室）\n",
    "Mr已婚男士\n",
    "Mrs已婚妇女\n",
    "Miss年轻未婚女子\n",
    "Master有技能的人/教师\n",
    "'''\n",
    "#姓名中头衔字符串与定义头衔类别的映射关系\n",
    "title_mapDict = {\n",
    "                    \"Capt\":       \"Officer\",\n",
    "                    \"Col\":        \"Officer\",\n",
    "                    \"Major\":      \"Officer\",\n",
    "                    \"Jonkheer\":   \"Royalty\",\n",
    "                    \"Don\":        \"Royalty\",\n",
    "                    \"Sir\" :       \"Royalty\",\n",
    "                    \"Dr\":         \"Officer\",\n",
    "                    \"Rev\":        \"Officer\",\n",
    "                    \"the Countess\":\"Royalty\",\n",
    "                    \"Dona\":       \"Royalty\",\n",
    "                    \"Mme\":        \"Mrs\",\n",
    "                    \"Mlle\":       \"Miss\",\n",
    "                    \"Ms\":         \"Mrs\",\n",
    "                    \"Mr\" :        \"Mr\",\n",
    "                    \"Mrs\" :       \"Mrs\",\n",
    "                    \"Miss\" :      \"Miss\",\n",
    "                    \"Master\" :    \"Master\",\n",
    "                    \"Lady\" :      \"Royalty\"\n",
    "                    }\n",
    " \n",
    "#map函数：对Series每个数据应用自定义的函数计算\n",
    "titleDf['Title'] = titleDf['Title'].map(title_mapDict)\n",
    " \n",
    "#使用get_dummies进行one-hot编码\n",
    "titleDf = pd.get_dummies(titleDf['Title'])\n",
    "titleDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "94eb41c2-9a98-4c38-8eca-e41b9b5b6cc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,titleDf],axis=1)\n",
    " \n",
    "#删掉姓名这一列\n",
    "full.drop('Name',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "43009351-38d5-4a4d-b5ce-877a62220cfe",
   "metadata": {},
   "outputs": [],
   "source": [
    "#存放客舱号信息\n",
    "cabinDf = pd.DataFrame()\n",
    " \n",
    "# '''\n",
    "# 客场号的类别值是首字母，例如：\n",
    "# C85 类别映射为首字母C\n",
    "# '''\n",
    "full[ 'Cabin' ] = full[ 'Cabin' ].map( lambda c : c[0] )\n",
    " \n",
    "##使用get_dummies进行one-hot编码，列名前缀是Cabin\n",
    "cabinDf = pd.get_dummies( full['Cabin'] , prefix = 'Cabin' )\n",
    " \n",
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,cabinDf],axis=1)\n",
    " \n",
    "#删掉客舱号这一列\n",
    "full.drop('Cabin',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "10991392-af22-4233-962f-30461b4815af",
   "metadata": {},
   "outputs": [],
   "source": [
    "#删掉船票这一列\n",
    "full.drop('Ticket',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "a924765c-0660-4ed4-885a-fb84aa4d0f71",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>FamilySize</th>\n",
       "      <th>Family_Single</th>\n",
       "      <th>Family_Small</th>\n",
       "      <th>Family_Large</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   FamilySize  Family_Single  Family_Small  Family_Large\n",
       "0           2              0             1             0\n",
       "1           2              0             1             0\n",
       "2           1              1             0             0\n",
       "3           2              0             1             0\n",
       "4           1              1             0             0"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#存放家庭信息\n",
    "familyDf = pd.DataFrame()\n",
    " \n",
    "# '''\n",
    "# 家庭人数=同代直系亲属数（Parch）+不同代直系亲属数（SibSp）+乘客自己\n",
    "# （因为乘客自己也是家庭成员的一个，所以这里加1）\n",
    "# '''\n",
    "familyDf[ 'FamilySize' ] = full[ 'Parch' ] + full[ 'SibSp' ] + 1\n",
    " \n",
    "# '''\n",
    "# 家庭类别：\n",
    "# 小家庭Family_Single：家庭人数=1\n",
    "# 中等家庭Family_Small: 2<=家庭人数<=4\n",
    "# 大家庭Family_Large: 家庭人数>=5\n",
    "# '''\n",
    "#if 条件为真的时候返回if前面内容，否则返回0\n",
    "familyDf[ 'Family_Single' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if s == 1 else 0 )\n",
    "familyDf[ 'Family_Small' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 2 <= s <= 4 else 0 )\n",
    "familyDf[ 'Family_Large' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 5 <= s else 0 )\n",
    " \n",
    "familyDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "83a103a8-b36e-48d8-98ae-8ec96edbdb56",
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,familyDf],axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "0e7acdef-de9f-401d-b9e2-ab1beecb8ded",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Survived         1.000000\n",
       "Mrs              0.344935\n",
       "Miss             0.332795\n",
       "Pclass_1         0.285904\n",
       "Family_Small     0.279855\n",
       "Fare             0.257307\n",
       "Cabin_B          0.175095\n",
       "Embarked_C       0.168240\n",
       "Cabin_D          0.150716\n",
       "Cabin_E          0.145321\n",
       "Cabin_C          0.114652\n",
       "Pclass_2         0.093349\n",
       "Master           0.085221\n",
       "Parch            0.081629\n",
       "Cabin_F          0.057935\n",
       "Royalty          0.033391\n",
       "Cabin_A          0.022287\n",
       "FamilySize       0.016639\n",
       "Cabin_G          0.016040\n",
       "Embarked_Q       0.003650\n",
       "PassengerId     -0.005007\n",
       "Cabin_T         -0.026456\n",
       "Officer         -0.031316\n",
       "SibSp           -0.035322\n",
       "Age             -0.070323\n",
       "Family_Large    -0.125147\n",
       "Embarked_S      -0.149683\n",
       "Family_Single   -0.203367\n",
       "Cabin_U         -0.316912\n",
       "Pclass_3        -0.322308\n",
       "Sex             -0.543351\n",
       "Mr              -0.549199\n",
       "Name: Survived, dtype: float64"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#相关性矩阵\n",
    "corrDf = full.corr() \n",
    "# '''\n",
    "# 查看各个特征与生成情况（Survived）的相关系数，\n",
    "# ascending=False表示按降序排列\n",
    "# '''\n",
    "corrDf['Survived'].sort_values(ascending =False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "66d648cd-a8df-413f-85d8-f9de98471d4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "#特征选择\n",
    "full_X = pd.concat( [titleDf,#头衔\n",
    "                     pclassDf,#客舱等级\n",
    "                     familyDf,#家庭大小\n",
    "                     full['Fare'],#船票价格\n",
    "                     cabinDf,#船舱号\n",
    "                     embarkedDf,#登船港口\n",
    "                     full['Sex']#性别\n",
    "                    ] , axis=1 )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "f52fc024-f93a-4218-a6bc-372b15e4700f",
   "metadata": {},
   "outputs": [],
   "source": [
    "#原始数据集有891行\n",
    "sourceRow=891\n",
    " \n",
    "# '''\n",
    "# sourceRow是我们在最开始合并数据前知道的，原始数据集有总共有891条数据\n",
    "# 从特征集合full_X中提取原始数据集提取前891行数据时，我们要减去1，因为行号是从0开始的。\n",
    "# '''\n",
    "#原始数据集：特征\n",
    "source_X = full_X.loc[0:sourceRow-1,:]\n",
    "#原始数据集：标签\n",
    "source_y = full.loc[0:sourceRow-1,'Survived']   \n",
    " \n",
    "#预测数据集：特征\n",
    "pred_X = full_X.loc[sourceRow:,:]\n",
    "# '''\n",
    "# 上面代码解释：\n",
    "# 891行前面的数据是测试数据集，891行之后的数据是预测数据集。[sourceRow:,:]就是从891行开始到最后一行作为预测数据集\n",
    "# '''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "5619559a-ca9a-4edb-9200-d438bd4ef575",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数据集有多少行: 891\n",
      "原始数据集有多少行: 418\n"
     ]
    }
   ],
   "source": [
    "# '''\n",
    "# 确保这里原始数据集取的是前891行的数据，不然后面模型会有错误\n",
    "# '''\n",
    "#原始数据集有多少行\n",
    "print('原始数据集有多少行:',source_X.shape[0])\n",
    "#预测数据集大小\n",
    "print('原始数据集有多少行:',pred_X.shape[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "f39d127e-4566-4033-94c7-28460e09eac4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数据集特征： (891, 27) 训练数据集特征： (712, 27) 测试数据集特征： (179, 27)\n",
      "原始数据集标签： (891,) 训练数据集标签： (712,) 测试数据集标签： (179,)\n"
     ]
    }
   ],
   "source": [
    "# '''\n",
    "# 从原始数据集（source）中拆分出训练数据集（用于模型训练train），测试数据集（用于模型评估test）\n",
    "# train_test_split是交叉验证中常用的函数，功能是从样本中随机的按比例选取train data和test data\n",
    "# train_data：所要划分的样本特征集\n",
    "# train_target：所要划分的样本结果\n",
    "# test_size：样本占比，如果是整数的话就是样本的数量\n",
    "# '''\n",
    "from sklearn.model_selection import train_test_split\n",
    " \n",
    "#建立模型用的训练数据集和测试数据集\n",
    "train_X, test_X, train_y, test_y = train_test_split(source_X ,\n",
    "                                                    source_y,\n",
    "                                                    train_size=.8)\n",
    " \n",
    "#输出数据集大小\n",
    "print ('原始数据集特征：',source_X.shape, \n",
    "       '训练数据集特征：',train_X.shape ,\n",
    "      '测试数据集特征：',test_X.shape)\n",
    " \n",
    "print ('原始数据集标签：',source_y.shape, \n",
    "       '训练数据集标签：',train_y.shape ,\n",
    "      '测试数据集标签：',test_y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "3d9373c9-ba9f-4d4c-9dd0-48bc11fe18fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 第1步：导入算法\n",
    "\n",
    "# 第2步：创建模型：\n",
    "# 逻辑回归（logisic regression）\n",
    "# from sklearn.linear_model import LogisticRegression\n",
    "# log_model = LogisticRegression()\n",
    " \n",
    "# 随机森林Random Forests Model\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "model = RandomForestClassifier(n_estimators=100)\n",
    " \n",
    "#支持向量机Support Vector Machines\n",
    "#from sklearn.svm import SVC, LinearSVC\n",
    "#svc_model = SVC()\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "fdbf6b5c-1ffb-4f54-96ef-e37218bef96a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前CPU使用率：2.300000%\n",
      "总内存：32400MB\n",
      "可用内存：15812MB\n",
      "已用内存：16587MB\n",
      "内存使用率：51%\n"
     ]
    }
   ],
   "source": [
    "#第3步：训练模型\n",
    "model.fit( train_X , train_y )\n",
    "\n",
    "# 获取CPU使用率\n",
    "cpu_usage = psutil.cpu_percent(interval=1)\n",
    "\n",
    "# 获取RAM使用情况\n",
    "ram_usage = psutil.virtual_memory()\n",
    "\n",
    "print(\"当前CPU使用率：%f%%\" % cpu_usage)\n",
    "print(\"总内存：%dMB\" % (ram_usage.total / 1024 / 1024))\n",
    "print(\"可用内存：%dMB\" % (ram_usage.available / 1024 / 1024))\n",
    "print(\"已用内存：%dMB\" % (ram_usage.used / 1024 / 1024))\n",
    "print(\"内存使用率：%d%%\" % ram_usage.percent)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "55af9097-bd1a-4b4f-b43e-31cda780e5db",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8324022346368715"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分类问题，score得到的是模型的正确率\n",
    "model.score(test_X , test_y )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "e471d185-05c7-45ab-b4f7-6696b73fcb41",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "召回率等评分\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        died       0.92      0.82      0.87       119\n",
      "    survived       0.71      0.85      0.77        60\n",
      "\n",
      "    accuracy                           0.83       179\n",
      "   macro avg       0.81      0.84      0.82       179\n",
      "weighted avg       0.85      0.83      0.84       179\n",
      "\n",
      "运行时间 5.505096912384033\n"
     ]
    }
   ],
   "source": [
    "# 随机森林的模型报告\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.metrics import roc_curve, auc\n",
    "\n",
    "y_predict = model.predict(test_X)\n",
    "print('召回率等评分')\n",
    "print(classification_report(y_predict, test_y, target_names=['died','survived']))\n",
    "# print('混淆矩阵')\n",
    "# print(confusion_matrix(y_predict, test_y))\n",
    "endtime = time.time()\n",
    "print('运行时间',endtime-starttime)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c70689e0-ccb2-497f-a81c-9c6f055d8f23",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
